package com.reprezen.swagedit.core.templates;

/*******************************************************************************
 * Copyright (c) 2008, 2016 itemis AG (http://www.itemis.eu) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.templates.DocumentTemplateContext;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateBuffer;
import org.eclipse.jface.text.templates.TemplateException;
import org.eclipse.jface.text.templates.TemplateTranslator;

/**
 * Modification of {@link org.eclipse.xtext.ui.editor.templates.XtextTemplateContext} with removed Xtext dependencies (
 * {@link org.eclipse.xtext.scoping.IScopeProvider} and
 * {@link org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext}) <br/>
 * <br/>
 * Represents an extended version of class {@link DocumentTemplateContext} to provide additional Xtext related
 * information and services for resolving a <code>Template</code>. Furthermore it fixes the indentation of the applied
 * template.
 * 
 * @author Michael Clay - Initial contribution and API
 * @author Sebastian Zarnekow
 */
public class SwaggerTemplateContext extends DocumentTemplateContext {

    public SwaggerTemplateContext(DocumentTemplateContext context) {
        super(context.getContextType(), context.getDocument(), context.getCompletionOffset(), context
                .getCompletionLength());
    }

    // Unmodified code from
    // org.eclipse.xtext.ui.editor.templates.XtextTemplateContext below

    @Override
    public TemplateBuffer evaluate(Template template) throws BadLocationException, TemplateException {
        if (!canEvaluate(template))
            return null;

        TemplateTranslator translator = createTemplateTranslator();
        TemplateBuffer buffer = translator.translate(template);

        getContextType().resolve(buffer, this);

        return buffer;
    }

    /**
     * @since 2.3
     */
    public TemplateBuffer evaluateForDisplay(Template template) throws BadLocationException, TemplateException {
        if (!canEvaluate(template))
            return null;

        TemplateTranslator translator = new TemplateTranslator();
        TemplateBuffer buffer = translator.translate(template);

        getContextType().resolve(buffer, this);

        return buffer;
    }

    protected TemplateTranslator createTemplateTranslator() {
        try {
            int offset = getStart();
            IRegion lineRegion = getDocument().getLineInformationOfOffset(offset);
            String line = getDocument().get(lineRegion.getOffset(), lineRegion.getLength());
            int i = 0;
            // support for array items
            StringBuilder indentation = new StringBuilder();
            while (i < line.length()) {
                char indentSymbol = line.charAt(i);
                if (Character.isWhitespace(indentSymbol)) {
                    indentation.append(indentSymbol);
                    i++;
                } else if ('-' == indentSymbol) {// array item
                    indentation.append(' ');
                    i++;
                } else {
                    break;
                }
            }
            if (i != 0)
                return new IndentationAwareTemplateTranslator(indentation.toString());
            return new TemplateTranslator();
        } catch (BadLocationException ex) {
            return new TemplateTranslator();
        }
    }

    public static class IndentationAwareTemplateTranslator extends TemplateTranslator {

        private final String indentation;

        public IndentationAwareTemplateTranslator(String indentation) {
            this.indentation = indentation;
        }

        @Override
        public TemplateBuffer translate(Template template) throws TemplateException {
            return translate(template.getPattern());
        }

        @Override
        public TemplateBuffer translate(String string) throws TemplateException {
            String withIndentation = string.replaceAll("(\r\n?)|(\n)", "$0" + indentation);
            return super.translate(withIndentation);
        }
    }

}